using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using System.Threading;

namespace StartMenuSearchLoader
{
	static class Program
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			string assemGuid = Assembly.GetExecutingAssembly().GetType().GUID.ToString();
			using (Mutex instance = new Mutex(false, assemGuid))
			{
				if (instance.WaitOne(0, false))
				{
					try
					{
						CopyFromUpdateDirectory();
					}
					catch (Exception e)
					{
						LogErrorToFile(e);
					}

					RunProgram();
				}
			}
		}

		private static void RunProgram()
		{
			string path = Path.GetFullPath("StartMenuSearcher.dll");
			Assembly assem = Assembly.LoadFile(path);
			Type program = assem.GetType("StartMenuSearcher.Program", true, false);
			MethodInfo mainMethod = program.GetMethod("Main", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
			mainMethod.Invoke(null, new object[] { });
		}

		private static void CopyFromUpdateDirectory()
		{
			if (Directory.Exists("Update"))
			{
				string parentPath = Path.GetFullPath(".");
				
				foreach(string filePath in Directory.GetFiles("Update"))
				{
					FileInfo file = new FileInfo(filePath);
					string newPath = Path.Combine(parentPath, file.Name);
					if (File.Exists(newPath))
						File.Delete(newPath);

					file.MoveTo(newPath);
				}

				foreach (string childDirectory in Directory.GetDirectories("Update"))
				{
					DirectoryInfo child = new DirectoryInfo(childDirectory);

					string newPath = Path.Combine(parentPath, child.Name);
					if (Directory.Exists(newPath))
						Directory.Delete(newPath, true);
					
					child.MoveTo(newPath);
				}

				Directory.Delete("Update", true); //should be empty, but we do a recursive delete just in case.
			}
		}

		private static void LogErrorToFile(Exception e)
		{
			try
			{
				StreamWriter writer = new StreamWriter("UpdaterExceptions.log", true);
				writer.WriteLine("Exception occurred at " + DateTime.Now.ToString());
				writer.WriteLine(e.Message);
				writer.WriteLine(e.StackTrace);
				writer.WriteLine();
				writer.Close();
			}
			catch (Exception)
			{
				//If this doesn't work...I give up.
			}
		}
	}
}